package com.caishi.lkx.user.login;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.caishi.lkx.common.config.DiamondConfig;
import com.caishi.lkx.common.ienum.DeviceType;
import com.caishi.lkx.common.util.SmsUtilService;
import com.caishi.lkx.user.config.ThirdOauthConfig;
import com.caishi.lkx.user.dto.LoginDto;
import com.caishi.lkx.user.ienum.type.Sex;
import com.caishi.lkx.user.ienum.type.UserType;
import com.caishi.lkx.user.model.IUserModel;
import com.caishi.lkx.user.model.LoginInfoModel;
import com.caishi.lkx.user.model.UserModel;
import com.caishi.lkx.user.service.ILoginInfoService;
import com.caishi.lkx.user.service.impl.UserServiceImpl;
import com.zzw.common.exception.BizException;
import com.zzw.common.exception.BizRuntimeException;
import com.zzw.common.file.OssPlugins;
import com.caishi.lkx.user.UserResultCode;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @Param:
 * @return
 * @Author: huangpeng
 * @Date: 2021/9/26 11:19
 * @Description:
 */
@Service("qqLoginService")
@Slf4j
class QQLoginServiceImpl implements LoginService, IThirdOauthService {

    @Resource
    private ThirdOauthConfig thirdOauthConfig;
    @Resource
    private DiamondConfig diamondConfig;

    @Resource
    private ILoginInfoService loginInfoService;

    @Resource
    private SmsUtilService smsUtilService;

    @Resource
    private UsernameLoginServiceImpl usernameLoginService;
    @Resource
    private ILoginInfoService userLoginService;
    @Resource
    private UserServiceImpl userService;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private OssPlugins cdnOssPlugins;

    @Override
    public Map<String, Object> getAccessToken(String code, DeviceType pc) {
        log.error("qq登录:开始获取accesstoken:code={},deviceTp={}", code, pc);
        if (StrUtil.isBlank(code)) {
            throw new BizRuntimeException(UserResultCode.thirdLoginCodeFail);
        }
        String appid = null;
        String secret = null;
        String accessTokenUrl = null;
        String redirectUrl = null;
        if (this.isPc(pc)) {
            appid = thirdOauthConfig.getQqWebAppId();
            secret = thirdOauthConfig.getQqWebAppSecret();
            accessTokenUrl = thirdOauthConfig.getQqWebAccessTokenUrl();
            redirectUrl = thirdOauthConfig.getQqWebRedirectUrl();
        } else {
            appid = thirdOauthConfig.getQqAppId();
            secret = thirdOauthConfig.getQqAppSecret();
            accessTokenUrl = thirdOauthConfig.getQqAccessTokenUrl();
            redirectUrl = thirdOauthConfig.getQqRedirectUrl();
        }

        if (StrUtil.isBlank(appid)) {
            throw new BizRuntimeException(UserResultCode.accessTokenFail);
        }

        String url = String.format(accessTokenUrl, appid, secret, code, redirectUrl);
        log.error("qq登录:获取tokenurl={}", url);
        String resp = HttpUtil.get(url);
        log.error("qq登录:获取token结果:{}", resp);
        return JSONObject.parseObject(resp);
    }

    public Map<String, Object> getOpenId(String accessToken) {
        String url = String.format(thirdOauthConfig.getQqWebOpenIdUrl(), accessToken);
        String resp = HttpUtil.get(url);
        return JSONObject.parseObject(resp);
    }

    public Map<String, Object> getUnionid(String accessToken) {
        String url = String.format(thirdOauthConfig.getQqWebUnionId(), accessToken);
        String resp = HttpUtil.get(url);
        return JSONObject.parseObject(resp);
    }

    @Override
    public Map<String, Object> getUserInfo(String accessToken, String openId, DeviceType pc) {
        String appid = null;
        if (this.isPc(pc)) {
            appid = thirdOauthConfig.getQqWebAppId();
        } else {
            appid = thirdOauthConfig.getQqAppId();
        }
        String url = String.format(thirdOauthConfig.getQqWebUserInfoUrl(), accessToken, openId, appid);
        String resp = HttpUtil.get(url);
        return JSONObject.parseObject(resp);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public LoginInfoModel loginBase(LoginDto loginDto, HttpServletRequest request, HttpServletResponse response) throws BizException {
        Map<String, Object> accessTokenMap = this.getAccessToken(loginDto.getCode(), loginDto.getDeviceType());
        System.err.println(accessTokenMap);
        String accessToken = accessTokenMap.get("access_token").toString();
        if (StrUtil.isBlank(accessToken)) {
            throw new BizException(UserResultCode.accessTokenFail);
        }
        Map<String, Object> unionmap = this.getUnionid(accessToken);
        String openId = unionmap.get("openid").toString();
        String unionId = unionmap.get("unionid").toString();
        if (StrUtil.isBlank(unionId)) {
            throw new BizException(UserResultCode.unionIdFail);
        }
        LoginInfoModel loginInfoModel = loginInfoService.selectFirstLoginInfoByCredentials(unionId, loginDto.getType());
        if (loginInfoModel == null) {
            Map<String, Object> userInfo = this.getUserInfo(accessToken, openId, loginDto.getDeviceType());
            return LoginInfoModel.builder()
                    .account(openId)
                    .certificate(unionId)
                    .loginType(loginDto.getType())
                    .user(thirdGenerateUser(userInfo))
                    .build();
        }
        return checkLoginInfo(loginInfoModel, loginDto);
    }

    @Override
    public IUserModel<?> thirdGenerateUser(Map<String, Object> userInfo) {
        UserModel userModel = new UserModel();
        userModel.addUserType(UserType.member);
        String headimgurl = userInfo.get("figureurl_qq_1").toString();
        if (StrUtil.isNotBlank(headimgurl)) {
            userModel.setHeader(cdnOssPlugins.webFileUploadSync(headimgurl));
            userModel.setHeader(headimgurl);
        }
        userModel.setName(userInfo.get("nickname").toString());
        String sex = userInfo.get("gender").toString();
        if ("男".equals(sex)) {
            userModel.setSex(Sex.boy);
        } else if ("女".equals(sex)) {
            userModel.setSex(Sex.girl);
        } else {
            userModel.setSex(Sex.unknown);
        }
        return userModel;

    }


}
